#include "OgreURLPrecompiledHeader.h"
#include "OgreURLArchive.h"

#include <OgreLogManager.h>

namespace Ogre
{

//-------------------------------------------------------------------------------------------------------------------------------------------------
URLArchive::URLArchive( const String& name, const String& archType )
: Archive(name, archType)
, mInitialised(false)
{
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
URLArchive::~URLArchive()
{
	// Unload archive
	unload();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
bool URLArchive::isCaseSensitive() const
{
	return false;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
void URLArchive::load()
{
	// Lock mutex
	OGRE_LOCK_AUTO_MUTEX

	// Is archive initialised?
	if( mInitialised )
		return;

	mInitialised = true;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
void URLArchive::unload()
{
	// Lock mutex
	OGRE_LOCK_AUTO_MUTEX

	// Is archive initialised?
	if( !mInitialised )
		return;

	// Crear archive file list
	mFileList.clear();

	mInitialised = false;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
DataStreamPtr URLArchive::open(const String& filename, bool readOnly) const
{
	OGRE_LOCK_AUTO_MUTEX

	// Is archive initialised?
	if( !mInitialised )
		return DataStreamPtr();

	return DataStreamPtr();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
StringVectorPtr URLArchive::list(bool recursive, bool dirs)
{
	OGRE_LOCK_AUTO_MUTEX

	StringVectorPtr ret = StringVectorPtr( OGRE_NEW_T( StringVector, MEMCATEGORY_GENERAL )(), SPFM_DELETE_T );

	for( FileInfoList::iterator it = mFileList.begin(); it != mFileList.end(); it++ )
	{
		if( (dirs == (it->compressedSize == size_t (-1))) && (recursive || it->path.empty()) )
		{
			ret->push_back(it->filename);
		}
	}
	
	return ret;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
FileInfoListPtr URLArchive::listFileInfo(bool recursive, bool dirs)
{
	OGRE_LOCK_AUTO_MUTEX
		
	FileInfoList* fil = OGRE_NEW_T( FileInfoList, MEMCATEGORY_GENERAL )();

	for( FileInfoList::iterator it = mFileList.begin(); it != mFileList.end(); it++ )
	{
		if( (dirs == (it->compressedSize == size_t (-1))) && (recursive || it->path.empty()) )
		{
			fil->push_back(*it);
		}
	}
	
	return FileInfoListPtr( fil, SPFM_DELETE_T );
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
StringVectorPtr URLArchive::find(const String& pattern, bool recursive, bool dirs)
{
	OGRE_LOCK_AUTO_MUTEX
	StringVectorPtr ret = StringVectorPtr( OGRE_NEW_T( StringVector, MEMCATEGORY_GENERAL )(), SPFM_DELETE_T );

	// If pattern contains a directory name, do a full match
	 bool full_match = (pattern.find ('/') != String::npos) || (pattern.find ('\\') != String::npos);
	 
	 for( FileInfoList::iterator it = mFileList.begin(); it != mFileList.end(); it++ )
	 {
		 if( ( dirs == (it->compressedSize == size_t (-1))) && (recursive || full_match || it->path.empty()))
		 {
			 // Check basename matches pattern (zip is case insensitive)
			 if( StringUtil::match( full_match ? it->filename : it->basename, pattern, false ) )
			 {
				 ret->push_back( it->filename );
			 }
		 }
	 }
	 
	 return ret;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
bool URLArchive::exists(const String& filename)
{
	OGRE_LOCK_AUTO_MUTEX
	// Itarate all files
	for( FileInfoList::iterator it = mFileList.begin(); it != mFileList.end(); it++ )
	{
		if( it->filename == filename )
			return true;
	}

	return false;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
time_t URLArchive::getModifiedTime(const String& filename)
{
	OGRE_LOCK_AUTO_MUTEX

	// Is archive initialised?
	if( !mInitialised )
		return 0;

	return 0;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------
FileInfoListPtr URLArchive::findFileInfo(const String& pattern, bool recursive, bool dirs)
{
	OGRE_LOCK_AUTO_MUTEX
	FileInfoListPtr ret = FileInfoListPtr( OGRE_NEW_T( FileInfoList, MEMCATEGORY_GENERAL )(), SPFM_DELETE_T );

    // If pattern contains a directory name, do a full match
    bool full_match = (pattern.find ('/') != String::npos) || (pattern.find ('\\') != String::npos);

    for( FileInfoList::iterator it = mFileList.begin(); it != mFileList.end(); it++ )
	{
        if( (dirs == (it->compressedSize == size_t (-1))) && (recursive || full_match || it->path.empty()))
		{
            // Check name matches pattern (zip is case insensitive)
            if( StringUtil::match( full_match ? it->filename : it->basename, pattern, false ) )
			{
				ret->push_back(*it);
			}
		}
	}

	return ret;
}

} // end of namespace Ogre
